package edu.lnu.project.timeeditapp.activites;

//TODO: Rename the name of this class to GraphicalView.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TableRow.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;

import com.lnu.project.timeeditapp.R;

import edu.lnu.project.timeeditapp.EventDialog.EventDetailedDialog;
import edu.lnu.project.timeeditapp.db.TimeEditDataSource;
import edu.lnu.project.timeeditapp.helper.MyHelper;
import edu.lnu.project.timeeditapp.parser.Event;

@SuppressWarnings({"deprecation", "unchecked", "unused"})
public class GridViewActivity extends Activity {

	//TODO:These variables can be in Helper class since they are static final.
	public static final String MONDAY = "Monday";
	public static final String TUESDAY = "Tuesday";
	public static final String WEDNESDAY = "Wednesday";
	public static final String THURSDAY = "Thursday";
	public static final String FRIDAY = "Friday";
	public static final String SATURDAY = "Saturday";
	public static final String SUNDAY = "Sunday";

	//TODO:These variables can be in Helper class since they are static final.
	public static enum day {MON, TUE, WED, THUR, FRI, SAT, SUN};

	public Activity myActivity;

	Button currentWeekButton;
	ImageButton nextWeekButton;
	ImageButton previousWeekButton;
	TextView weekView;

	int currentWeek;
	TimeEditDataSource datasource;
	ArrayList<Event> eventList;
	ArrayList<Event> allEventsList;
	HashMap<String, ArrayList<Event>> dayEventList;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		activtySettings(this);
		MyHelper.initializeSharedPreferences(this);
		currentWeek = MyHelper.currentWeek;
		setContentView(R.layout.gridview_activity);
		weekView = (TextView) findViewById(R.id.textViewListViewWeek);
		weekView.setText("Week "+currentWeek);

		myActivity = this;
		datasource = new TimeEditDataSource(this);
		initializeAllEventsList();
		initializeWeekButton();
		initializeDaysHashMap();

	}

	@Override
	protected void onResume() {
		//Check orientation and start correct activity
		MyHelper.initializeSharedPreferences(this);
		checkForCorrectOrientation();
		drawTable();
		super.onResume();
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) { 
		super.onConfigurationChanged(newConfig);

		// Checks the orientation of the screen
		if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
			MyHelper.currentWeek = currentWeek;
			/* Start new Activity DebugActivity */
			Intent intent = new Intent(this, ListViewActivity.class);
			intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
			this.startActivity(intent);

		} else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
			if(currentWeek != MyHelper.currentWeek){
				currentWeek = MyHelper.currentWeek;
				MyHelper.initializeSharedPreferences(myActivity);
				drawTable();
				weekView.setText("Week "+currentWeek);
			}
		}
	}

	/**
	 * Check orientation and destroy the current activity if the orientation has changed to Portraid
	 */
	private void checkForCorrectOrientation(){
		// Check so the orientation is correct for this activity
		if( getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE ){
			//set the static week number so portraid mode can show the same week
			MyHelper.currentWeek = currentWeek;
			//Destroy activity
			finish();
		}
	}

	//Assign events to days hashMap by the names of their begin dates.
	public void initializeDaysHashMap(){
		dayEventList = new HashMap<String, ArrayList<Event>>();

		dayEventList.put(MONDAY, new ArrayList<Event>());
		dayEventList.put(TUESDAY, new ArrayList<Event>());
		dayEventList.put(WEDNESDAY, new ArrayList<Event>());
		dayEventList.put(THURSDAY, new ArrayList<Event>());
		dayEventList.put(FRIDAY, new ArrayList<Event>());
		dayEventList.put(SATURDAY, new ArrayList<Event>());
		dayEventList.put(SUNDAY, new ArrayList<Event>());

		eventList = (ArrayList<Event>) getEventsForCurrentWeek();

		for (Event event : eventList) {
			try{
				dayEventList.get(MyHelper.getDayName(event.getBeginDate().toString())).add(event);

			}
			catch(NullPointerException e){System.err.println("Beign Date is incorrect");}
		}
	}

	//Get all events from database.
	public void initializeAllEventsList(){
		datasource.open();
		allEventsList = datasource.getAllEvents();
		datasource.close();
	}

	public void drawAllTextViews(int color, String day, int hour, TableRow tr){
		ArrayList<Event> eventListDay = dayEventList.get(day);

		if(eventListDay.size() != 0){
			
			//list of events: courses for example at 8 o'clock on Monday (hopefully only one course)
			ArrayList<Event> eventsInRange = new ArrayList<Event>();
			
			for (Event event : eventListDay) {
				if(isInRange(event, hour)){
					eventsInRange.add(event);
				}
			}
			if(eventsInRange.size() >0){
				if(eventsInRange.size()>1){ //conflict
					drawTextView(eventsInRange, color, day, hour, tr);
				}
				else{
					drawTextView(eventsInRange.get(0), color, day, hour, tr);
				}
			}
			else{ //Draw a blank border textView
				drawTextView(day, hour, tr);
			}

		}
		else{ //Draw a blank border textView
			drawTextView(day, hour, tr);
		}


	}

	//Regular events
	public void drawTextView(Event event, int color, String day, int hour, TableRow tr){

		TextView column=new TextView(GridViewActivity.this);
		column.setText(event.getCourse());
		if(MyHelper.isRedDay(event)){
			column.setTextSize(10f);
			column.setBackgroundColor(Color.RED);
		}
		else{
			column.setBackgroundColor(getColor(event.getCourse()));
			column.setTextSize(15f);
		}
		column.setTag(event.getId());
		column.setOnClickListener(new MyOnClickListener());
		column.setLayoutParams(new LayoutParams(0, 90, 2f));
		column.setGravity(Gravity.CENTER);
		tr.addView(column);
	}



	//Events that are in conflict
	public void drawTextView(ArrayList<Event> conflictEvents, int color, String day, int hour, TableRow tr){
		//if it is more than 2 courses make a general warning sign and make a new dialog to direct the person to the responsible(email)
		int sizeConflict = conflictEvents.size();
		if(sizeConflict < 4){
			float weight = 1f;
			if(sizeConflict == 3){
				weight = 2/3f;
			}
			if(sizeConflict == 2){
				weight = 2/2f;
			}
			LinearLayout warningFrame = new LinearLayout(GridViewActivity.this);
			warningFrame.setLayoutParams(new LayoutParams(0, 90, 2f));
			ArrayList<Event> eventsInConflict = new ArrayList<Event>();
			for (Event event : conflictEvents) {
				TextView column=new TextView(GridViewActivity.this);
				if(MyHelper.isRedDay(event.getCourse())){
					column.setBackgroundColor(Color.RED);
				}
				else{
					column.setBackgroundColor(getColor(event.getCourse()));
				}
				eventsInConflict.add(event);
				column.setLayoutParams(new LayoutParams(0, LayoutParams.MATCH_PARENT, weight));
				column.setGravity(Gravity.CENTER);

				warningFrame.addView(column);
			}
			warningFrame.setTag(eventsInConflict);
			warningFrame.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					ArrayList<Event> eventsInConflict = (ArrayList<Event>) v.getTag();
					showWarningDialog(null, false, eventsInConflict);
				}
			});
			tr.addView(warningFrame);
		}
		else{
			String warningText = "";
			for (Event event : conflictEvents) {
				warningText += event.getCourse()+", ";
			}
			StringBuilder stringbuilder = new StringBuilder(warningText);
			stringbuilder.replace(warningText.lastIndexOf(","), warningText.lastIndexOf(",") + 1, "." );

			FrameLayout warningFrame = new FrameLayout(GridViewActivity.this);
			warningFrame.setBackgroundColor(Color.RED);
			warningFrame.setLayoutParams(new LayoutParams(0, 90, 2f));

			ImageView column = new ImageView(GridViewActivity.this);
			column.setBackgroundResource(android.R.drawable.ic_dialog_alert);
			column.setTag(warningText);// warningText in order to distinguish that it's a warning
			column.setOnClickListener(new MyOnClickListener());
			column.setLayoutParams(new LayoutParams(android.view.WindowManager.LayoutParams.FILL_PARENT, android.view.WindowManager.LayoutParams.FILL_PARENT));
			warningFrame.addView(column);
			tr.addView(warningFrame);
		}
	}
	
	//Draw blank
	public void drawTextView(String day, int hour, TableRow tr){
		TextView column=new TextView(GridViewActivity.this);
		column.setText("");
		column.setBackgroundColor(getResources().getColor(R.color.LightYellow));
		column.setTextSize(15f);
		column.setLayoutParams(new LayoutParams(0, 90, 2f));
		column.setGravity(Gravity.CENTER);
		tr.addView(column);
	}

	public class MyOnClickListener implements View.OnClickListener{

		@Override
		public void onClick(View v) {
			try{
				int eventId = (Integer) v.getTag();

				datasource.open();
				Event event = datasource.getEvent(eventId);

				if(!MyHelper.isRedDay(event)){
					EventDetailedDialog eventDetailedDialog = new EventDetailedDialog(myActivity, event);
					eventDetailedDialog.setCanceledOnTouchOutside(true);
					eventDetailedDialog.show();
				}
				datasource.close();
			}
			catch(ClassCastException e){
				String warningText = v.getTag().toString();
				//TODO:warning text can be in helper so it can be changed easily to adapt preference and language differences.
				warningText = "Too many courses: "+warningText+" Please contact: ";
				showWarningDialog(warningText, true, null);
			}

		}}

	/**
	 * 
	 * @param warningText the text that will be shown as a warning.
	 * @param tooMany this indicates that there are too many courses to
	 *  list so it will be a warning to direct the student to the responsible department.
	 * @param eventsInConflict
	 */
	public void showWarningDialog(String warningText, boolean tooMany, ArrayList<Event> eventsInConflict){

		if(tooMany){
			//Show the warning dialog
			LayoutInflater inflater = LayoutInflater.from(this);
			final View dialogView = inflater.inflate(R.layout.warning_dialog, null);
			TextView warningTextView = (TextView) dialogView.findViewById(R.id.warning_text);
			TextView warningEmail = (TextView) dialogView.findViewById(R.id.warning_email);
			warningEmail.setText(Html.fromHtml("<a href=\"mailto:studera@lnu.se\"> Email Responsible </a>"));
			warningEmail.setMovementMethod(LinkMovementMethod.getInstance());
			warningTextView.setText(warningText);
			new AlertDialog.Builder(this)
			.setTitle("Conflicting Courses!").setIcon(android.R.drawable.ic_dialog_alert).setView(dialogView)
			.setPositiveButton(android.R.string.ok, null).show();
		}

		else{
			
			LinearLayout mainLayout = new LinearLayout(GridViewActivity.this);
			mainLayout.setLayoutParams(new LayoutParams(android.view.WindowManager.LayoutParams.FILL_PARENT,
					android.view.WindowManager.LayoutParams.FILL_PARENT));
			mainLayout.setOrientation(LinearLayout.VERTICAL);

			LinearLayout listOfCoursesLayout = new LinearLayout(GridViewActivity.this);
			listOfCoursesLayout.setLayoutParams(new LayoutParams(android.view.WindowManager.LayoutParams.FILL_PARENT,
					android.view.WindowManager.LayoutParams.FILL_PARENT));
			listOfCoursesLayout.setOrientation(LinearLayout.HORIZONTAL);

			for (Event event : eventsInConflict) {
				TextView column = new TextView(GridViewActivity.this);
				column.setText(event.getCourse());
				column.setBackgroundDrawable(getResources().getDrawable(R.drawable.round_corners_lite));
				column.setTextSize(15f);
				column.setTag(event.getId());
				column.setOnClickListener(new MyOnClickListener());
				column.setLayoutParams(new LayoutParams(0, 90, 2f));
				column.setGravity(Gravity.CENTER);
				listOfCoursesLayout.addView(column);
			}
			//"Contact email" textview****
			TextView warningEmail = new TextView(GridViewActivity.this);
			warningEmail.setText(Html.fromHtml("<a href=\"mailto:studera@lnu.se\">  Email Responsible </a>"));
			warningEmail.setTextSize(20f);
			warningEmail.setMovementMethod(LinkMovementMethod.getInstance());
			warningEmail.setGravity(Gravity.CENTER);
			//****

			mainLayout.addView(listOfCoursesLayout);
			mainLayout.addView(warningEmail);
			new AlertDialog.Builder(this)
			.setTitle("Conflicting Courses!").setIcon(android.R.drawable.ic_dialog_alert).setView(mainLayout)
			.setPositiveButton(android.R.string.ok, null).show();

		}
	}


	//Go through 7 days and 24 hours and, on the way, draw the textviews on table.
	public void drawTable(){
		
		initializeDaysHashMap();

		View vline = new View(GridViewActivity.this);
		vline.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, 8));
		vline.setBackgroundColor(getResources().getColor(R.color.DayBrownBack));

		TableLayout tv=(TableLayout) findViewById(R.id.tableLayout);
		tv.removeAllViewsInLayout();
		tv.addView(vline);

		TableRow tr = null;

		for(int i = 0; i<=23; i++){ //24 hours 
			tr = new TableRow(GridViewActivity.this);

			tr.setLayoutParams(new LayoutParams(
					LayoutParams.FILL_PARENT,
					LayoutParams.WRAP_CONTENT));

			for(int j = 0; j<=7; j++){ //7 days + 1 column for hours.

				//get events according to day
				int hour = i;
				switch (j){
				case (0):{ //Hour
					TextView column=new TextView(this);
					column.setText(hour+"");
					column.setBackgroundColor(getResources().getColor(R.color.DayBrownBack));
					column.setTextColor(getResources().getColor(R.color.DayYellow));
					column.setLayoutParams(new LayoutParams(0, 90, 1f));
					column.setGravity(Gravity.FILL);
					column.setTextSize(20f);
					tr.addView(column);
					break;
				}
				case (1):{//Monday
					drawAllTextViews(Color.CYAN, MONDAY, hour, tr);
					break;
				}
				case (2):{//Tuesday
					drawAllTextViews(Color.MAGENTA, TUESDAY, hour, tr);
					break;
				}
				case (3):{//Wednesday
					drawAllTextViews(Color.YELLOW, WEDNESDAY, hour, tr);
					break;
				}
				case (4):{//Thursday
					drawAllTextViews(Color.GREEN, THURSDAY, hour, tr);
					break;
				}
				case (5):{//Friday
					drawAllTextViews(Color.GRAY, FRIDAY, hour, tr);
					break;
				}
				case (6):{//Saturday
					drawAllTextViews(Color.RED, SATURDAY, hour, tr);
					break;
				}
				case (7):{ //Sunday
					drawAllTextViews(Color.RED, SUNDAY, hour, tr);
					break;
				}
				default:
					System.out.println("DEFAULT");
					break;
				}
			}
			tv.addView(tr);
		}

		//A line between the table and the bottom of the screean.
		vline = new View(GridViewActivity.this);
		vline.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, 8));
		vline.setBackgroundColor(getResources().getColor(R.color.DayBrownBack));
		tv.addView(vline);

	}

	//get the events from the database according to current week.
	private ArrayList<Event> getEventsForCurrentWeek(){

		datasource.open();
		ArrayList<Event> events = datasource.getWeekEvents(currentWeek);
		datasource.close();
		return events;
	}

	//Check if the event is in the range of the specific day x hour (Eg: Monday x 13h)
	public boolean isInRange(Event event, int time){
		if(isVisible(event.getCourse())){
			int beginHour = 0;
			int beginMinute = 0 ;

			int endHour = 0;
			int endMinute = 0;

			try{
				SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");

				Date beginTime = timeFormat.parse(event.getBeginTime().toString());
				Date endTime = timeFormat.parse(event.getEndTime().toString());

				beginHour = beginTime.getHours();
				beginMinute = beginTime.getMinutes();

				endHour = endTime.getHours();
				endMinute = endTime.getMinutes();
			} catch (ParseException e) {
				System.err.println("Beign Date");
			}

			if(MyHelper.isEndDateLater(event)){
				endHour = 23;
				endMinute = 59;
			}


			if(endMinute>0 ){
				endHour++;
			}
			for (int i = beginHour; i < endHour; i++) {
				if(i == time){
					return true;
				}
			}
			return false;
		}
		else{
			return false;
		}

	}

	public void initializeWeekButton(){
		currentWeekButton = (Button) findViewById(R.id.buttonListViewCurrentWeek);
		nextWeekButton = (ImageButton) findViewById(R.id.buttonListViewNextWeek);
		previousWeekButton = (ImageButton) findViewById(R.id.buttonListViewPreviousWeek);

		currentWeekButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {

				currentWeek = MyHelper.getCurrentWeek();
				weekView.setText("Week "+currentWeek);
				initializeDaysHashMap();
				drawTable();
			}
		});
		nextWeekButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				currentWeek = MyHelper.changeWeek(currentWeek, 1);
				weekView.setText("Week "+currentWeek);
				drawTable();

			}
		});
		previousWeekButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				currentWeek = MyHelper.changeWeek(currentWeek, -1);
				weekView.setText("Week "+currentWeek);
				drawTable();
			}
		});
	}
	
	private void activtySettings(Activity a){
		//Remove title bar
		a.requestWindowFeature(Window.FEATURE_NO_TITLE);

		//Remove notification bar
		a.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
	}

	public int getColor(String courseName){
		Resources res = getResources();
		return res.getColor(MyHelper.visibilityColorPreferences.getInt(courseName+MyHelper.COLOR, Color.RED));

	}

	public boolean isVisible(String courseName){
		return MyHelper.visibilityColorPreferences.getBoolean(courseName+MyHelper.VISIBILITY, true);
	}
}
